/* ************************************************************************
> File Name:     stress_test.cpp
> Author:        程序员Carl
> 微信公众号:    代码随想录
> Created Time:  Sun 16 Dec 2018 11:56:04 AM CST
> Description:
 ************************************************************************/

 #include <iostream>
 #include <chrono>
 #include <cstdlib>
 #include <pthread.h>
 #include <time.h>
 #include "skip_list.hpp"

 #define NUM_THREADS 1
 #define TEST_COUNT 100000

 SkipList<int, std::string>* skipList = SkipList<int, std::string>::create_skip_list(16);

 void *insertElement(void* threadid) {
     long long  tid;
    //  long * tp = (long long*)threadid;
     tid = (long long)threadid;
    //  tid = reinterpret_cast<long>(tp);
     std::cout << tid << std::endl;
     int tmp = TEST_COUNT/NUM_THREADS;
     for (int i=tid*tmp, count=0; count<tmp; i++) {
         count++;
         skipList->insert(rand() % TEST_COUNT, "a");
     }
     pthread_exit(NULL);
 }

 void *getElement(void* threadid) {
     long long tid;
     tid = (long long)threadid;

    //  tid = reinterpret_cast<long>(threadid);
     std::cout << tid << std::endl;
     int tmp = TEST_COUNT/NUM_THREADS;
     for (int i=tid*tmp, count=0; count<tmp; i++) {
         count++;
         std::string a;
         skipList->find(rand() % TEST_COUNT, a);
     }
     pthread_exit(NULL);
 }

 int main() {
     srand (time(NULL));
     {

         pthread_t threads[NUM_THREADS];
         int rc;
         int i;

         auto start = std::chrono::high_resolution_clock::now();

         for( i = 0; i < NUM_THREADS; i++ ) {
             std::cout << "main() : creating thread, " << i << std::endl;
             rc = pthread_create(&threads[i], NULL, insertElement, (void *)i);

             if (rc) {
                 std::cout << "Error:unable to create thread," << rc << std::endl;
                 exit(-1);
             }
         }

         void *ret;
         for( i = 0; i < NUM_THREADS; i++ ) {
             if (pthread_join(threads[i], &ret) !=0 )  {
                 perror("pthread_create() error");
                 exit(3);
             }
         }
         auto finish = std::chrono::high_resolution_clock::now();
         std::chrono::duration<double> elapsed = finish - start;
         std::cout << "insert elapsed:" << elapsed.count() << std::endl;
     }





     skipList->traverse();

     {
         pthread_t threads[NUM_THREADS];
         int rc;
         int i;
         auto start = std::chrono::high_resolution_clock::now();

         for( i = 0; i < NUM_THREADS; i++ ) {
             std::cout << "main() : creating thread, " << i << std::endl;
             rc = pthread_create(&threads[i], NULL, getElement, (void *)i);

             if (rc) {
                 std::cout << "Error:unable to create thread," << rc << std::endl;
                 exit(-1);
             }
         }

         void *ret;
         for( i = 0; i < NUM_THREADS; i++ ) {
             if (pthread_join(threads[i], &ret) !=0 )  {
                 perror("pthread_create() error");
                 exit(3);
             }
         }

         auto finish = std::chrono::high_resolution_clock::now();
         std::chrono::duration<double> elapsed = finish - start;
         std::cout << "get elapsed:" << elapsed.count() << std::endl;
     }

     pthread_exit(NULL);
     return 0;

 }
